﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using System.Xml;
using System.Runtime.Serialization.Formatters.Binary;

namespace Fsb.Utility
{
    public class SerializableUtility
    {
        public static string XmlSerializer(object obj)
        {
            XmlSerializer serializer = new XmlSerializer(obj.GetType());
            using (MemoryStream ms = new MemoryStream())
            {
                using (XmlTextWriter xtw = new System.Xml.XmlTextWriter(ms, Encoding.UTF8))
                {
                    xtw.Formatting = System.Xml.Formatting.Indented;
                    serializer.Serialize(xtw, obj);

                    return Encoding.UTF8.GetString(ms.ToArray());
                }
            }
        }

        public static void XmlSerializerToFile(object obj, string fileName)
        {
            if (File.Exists(fileName)) File.Delete(fileName);

            if (!Directory.Exists(Path.GetDirectoryName(fileName))) Directory.CreateDirectory(Path.GetDirectoryName(fileName));

            using (FileStream ms = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None))
            {
                byte[] data = Encoding.UTF8.GetBytes(XmlSerializer(obj));
                ms.Write(data, 0, data.Length);
            }
        }

        public static T XmlDeSerializer<T>(string xml)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(T));

            using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
            {
                using (XmlTextReader xtw = new System.Xml.XmlTextReader(ms))
                {
                    return (T)serializer.Deserialize(xtw);
                }
            }
        }

        public static T XmlDeSerializerFromFile<T>(string fileName)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(T));

            using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (XmlTextReader xtw = new System.Xml.XmlTextReader(fs))
                {
                    return (T)serializer.Deserialize(xtw);
                }
            }
        }

        public static void BinarySerializer(object obj, Stream stream)
        {
            BinaryFormatter formatter = new BinaryFormatter();
            formatter.Serialize(stream, obj);
        }

        public static void BinarySerializerToFile(object obj, string fileName)
        {
            if (File.Exists(fileName)) File.Delete(fileName);

            if (!Directory.Exists(Path.GetDirectoryName(fileName))) Directory.CreateDirectory(Path.GetDirectoryName(fileName));

            using (FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None))
            {
                BinarySerializer(obj, fs);
            }
        }

        public static T BinaryDeSerializer<T>(Stream stream)
        {
            BinaryFormatter formatter = new BinaryFormatter();
            T t = (T)formatter.Deserialize(stream);

            return t;
        }

        public static T BinaryDeSerializerFromFile<T>(string fileName)
        {
            using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                return BinaryDeSerializer<T>(fs);
            }
        }
    }
}
